package cn.com.open.itembank.controller;

import cn.com.open.itembank.common.enums.AnswerType;
import cn.com.open.itembank.common.enums.PaperImportType;
import cn.com.open.itembank.dto.*;
import cn.com.open.itembank.exception.PoiException;
import cn.com.open.itembank.service.PaperExportService;
import cn.com.open.itembank.service.PaperService;
import cn.com.open.itembank.service.RulesService;
import net.lingala.zip4j.exception.ZipException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Map;

/**
 * Created by lucky on 2017/10/30.
 */
@RestController
@RequestMapping(value = "/itembank")
public class ItemBankController {

    @Autowired
    private PaperService service;

    @Autowired
    private RulesService rulesService;

    @Autowired
    private PaperExportService paperExportService;


    //region 查询相关

    //region 获取指定题库下指定试卷

    /**
     * 获取指定题库下指定试卷全部信息.
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @return 试卷模型 full item
     */
    @GetMapping(value = "/{itemBankId}/paper/{id}")
    public ReturnModel getFullPaper(@PathVariable("itemBankId") String itemBankId, @PathVariable(value = "id") String id) {
        return service.getTestPaper(itemBankId, id, AnswerType.ALL, false);
    }

    /**
     * 获取指定题库下指定试卷答案信息.
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @return 试卷答案模型 item answer
     */
    @GetMapping(value = "/{itemBankId}/paper/{id}/answer")
    public ReturnModel getPaperAnswer(@PathVariable("itemBankId") String itemBankId, @PathVariable(value = "id") String id) {
        return service.getTestPaper(itemBankId, id, AnswerType.ANSWER, false);
    }

    /**
     * 获取指定题库下指定试卷不含答案的信息.
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @return 试卷无答案模型 item without answer
     */
    @GetMapping(value = "/{itemBankId}/paper/{id}/withoutanswer")
    public ReturnModel getPaperWithoutAnswer(@PathVariable("itemBankId") String itemBankId, @PathVariable(value = "id") String id) {
        return service.getTestPaper(itemBankId, id, AnswerType.NOANSWER, false);
    }
    //endregion

    //region 获取所有试卷列表

    /**
     * 获取所有试卷列表
     * 历史接口：~/openapi/v3/ItemBank/{itembankid}/papers
     *
     * @param itemBankId the item bank id
     * @param testPaperSearchDto   the testPaperSearchDto
     * @return the return model
     */
    @PostMapping(value = "/{itemBankId}/paper/list")
    public ReturnModel getPaperList(@PathVariable(value = "itemBankId") String itemBankId, @RequestBody TestPaperSearchDto testPaperSearchDto) {

        return service.getPaperList(itemBankId, testPaperSearchDto);
    }

    //endregion

    //endregion

    //region 更新相关

    //region 切换试卷状态

    /**
     * 切换试卷状态.
     * 历史接口：/openapi/v3/paper/{id}/UpdateStatus
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @param appKey     appKey
     * @return the return model
     */
    @PutMapping(value = "/{itemBankId}/paper/{id}/status")
    public ReturnModel updateStatus(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                    @RequestParam("appKey") String appKey) {
        return service.updateStatus(itemBankId, id, appKey);
    }

    //endregion

    //region 试卷名称修改

    /**
     * 试卷名称修改.
     * 历史接口：/openapi/v3/paper/{pid}/Title
     *
     * @param itemBankId    题库id
     * @param id            试卷id
     * @param testPaperName 试卷名称
     * @param appKey        appKey
     * @return the return model
     */
    @PutMapping(value = "/{itemBankId}/paper/{id}/title")
    public ReturnModel updateTestPaperName(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                           @RequestParam("c") String testPaperName, @RequestParam("appKey") String appKey) {
        return service.updateTestPaperName(itemBankId, id, testPaperName, appKey);
    }

    //endregion

    //region 发布试卷

    /**
     * 发布试卷.
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @param publisher  发布人
     * @param appKey     appKey
     * @return the return model
     */
    @PutMapping(value = "/{itemBankId}/paper/{id}/release")
    public ReturnModel testPaperRelease(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                        @RequestParam("publisher") String publisher, @RequestParam("appKey") String appKey) {
        return service.testPaperRelease(itemBankId, id, publisher, appKey);
    }
    //endregion

    //region 取消试卷发布

    /**
     * 取消试卷发布.
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @param appKey     appKey
     * @return the return model
     */
    @PutMapping(value = "/{itemBankId}/paper/{id}/cancelrelease")
    public ReturnModel cancelTestPaperRelease(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                              @RequestParam("appKey") String appKey) {
        return service.cancelTestPaperRelease(itemBankId, id, appKey);
    }
    //endregion

    //endregion

    //region 新增相关

    //region 试卷主体新增

    /**
     * 试卷主体新增
     *
     * @param itemBankId 题库id
     * @param paperModel 试卷模型
     * @param appKey     appKey
     * @return return model haimeidaone
     */
    @PostMapping(value = "/{itemBankId}/paper")
    public ReturnModel addPaper(@PathVariable(value = "itemBankId") String itemBankId,
                                @RequestBody PaperModel paperModel, @RequestParam("appKey") String appKey) {
        paperModel.setP3(itemBankId);
        return service.addPaper(itemBankId, paperModel, appKey);
    }
    //endregion

    //region 试卷复制

    /**
     * 试卷复制
     *
     * @param itemBankId 题库ID
     * @param oldId      旧试卷ID
     * @param newId      新试卷ID
     * @param appKey     appkey
     * @return return model
     */
    @PostMapping(value = "/{itemBankId}/paper/{oldId}/copyto/{newId}")
    public ReturnModel copyTestPaper(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "oldId") String oldId, @PathVariable(value = "newId") String newId,
                                     @RequestParam("appKey") String appKey) {
        return service.copyTestPaper(itemBankId, oldId, newId, appKey);
    }
    //endregion

    //region 跨题库批量复制试卷

    /**
     * 跨题库批量复制试卷.
     *
     * @param sourceItembankId 原题库id
     * @param targetItemBankId 目标题库id
     * @param targetOrgId      目标题库机构id
     * @param testPaperMap     旧新试题id的map
     * @return the map
     */
    @PostMapping(value = "/{itemBankId}/copypaperto/{targetItemBankId}")
    public Map<String, String> copyCrossItemBank(@PathVariable(value = "itemBankId") String sourceItembankId,
                                                 @PathVariable(value = "targetItemBankId") String targetItemBankId,
                                                 @RequestParam("targetOrgId") String targetOrgId, @RequestBody Map<String, String> testPaperMap) {
        return service.copyCrossItemBank(sourceItembankId, targetItemBankId, targetOrgId, testPaperMap);
    }
    //endregion

    //endregion

    //region 删除相关

    //region 试卷删除

    /**
     * 试卷删除(默认删除是自动取消发布后删除)
     *
     * @param itemBankId   题库id
     * @param id           试卷ID
     * @param isAutoDelete the is auto delete
     * @param appKey       appkey
     * @return return model
     */
    @DeleteMapping(value = "/{itemBankId}/paper/{id}/deleteauto")
    public ReturnModel deleteAuto(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                  @RequestParam("isAutoDelete") boolean isAutoDelete, @RequestParam("appKey") String appKey) {
        return service.deleteAuto(itemBankId, id, isAutoDelete, appKey);
    }
    //endregion

    //endregion

    //region 大题相关

    //region 大题自身删除

    /**
     * 大题自身删除
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @param index      大题序号
     * @param appKey     appKey
     * @return return model
     */
    @DeleteMapping(value = "/{itemBankId}/paper/{id}/section/{index}")
    public ReturnModel removeSection(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                     @PathVariable("index") String index, @RequestParam("appKey") String appKey) {
        return service.removeSection(itemBankId, id, index, appKey);
    }

    //endregion

    //region 大题所含试题删除

    /**
     * 大题所含试题删除
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @param questionId 试题id
     * @param index      大题序号
     * @param appKey     appKey
     * @return return model
     */
    @DeleteMapping(value = "/{itemBankId}/paper/{id}/section/{index}/question/{questionId}")
    public ReturnModel removeSectionQuestion(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                             @PathVariable("questionId") String questionId, @PathVariable("index") String index, @RequestParam("appKey") String appKey) {
        return service.removeSectionQuestion(itemBankId, id, index, questionId, appKey);
    }

    //endregion

    //region 大题批量试题删除

    /**
     * 大题批量试题删除
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @param idList 试题id集合
     * @param appKey     appKey
     * @return return model
     */
    @DeleteMapping(value = "/{itemBankId}/paper/{id}/question")
    public ReturnModel removeSectionQuestionList(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                             @RequestBody IdentifierArray idList, @RequestParam("appKey") String appKey) {
        return service.removeSectionQuestionList(itemBankId, id, idList.getIdList(), appKey);
    }

    //endregion

    //region 大题内容修改

    /**
     * 大题内容修改
     *
     * @param itemBankId   题库id
     * @param id           试卷id
     * @param index        大题序号
     * @param sectionTitle 大题标题
     * @param shuf         是否乱序
     * @param appKey       appKey
     * @return return model
     */
    @PutMapping(value = "/{itemBankId}/paper/{id}/section/{index}")
    public ReturnModel updateSectionContent(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                            @PathVariable("index") String index, @RequestParam("c") String sectionTitle, @RequestParam("shuf") boolean shuf, @RequestParam("appKey") String appKey) {
        return service.updateSectionContent(itemBankId, id, index, sectionTitle, shuf, appKey);
    }

    //endregion

    //region 大题试题分值修改

    /**
     * 大题试题分值修改
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @param index      大题序号
     * @param questionId 试题id
     * @param score      试题分值
     * @param appKey     appKey
     * @return return model
     */
    @PutMapping(value = "/{itemBankId}/paper/{id}/section/{index}/question/{questionId}/score")
    public ReturnModel updateSectionQuestionScore(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                                  @PathVariable("index") String index, @PathVariable("questionId") String questionId, @RequestParam("s") double score, @RequestParam("appKey") String appKey) {
        return service.updateSectionQuestionScore(itemBankId, id, index, questionId, score, appKey);
    }

    //endregion

    //region 大题所有试题分值修改

    /**
     * 大题所有试题分值修改
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @param index      大题序号
     * @param score      试题分值
     * @param appKey     appKey
     * @return return model
     */
    @PutMapping(value = "/{itemBankId}/paper/{id}/section/{index}/score")
    public ReturnModel updateSectionScore(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                          @PathVariable("index") String index, @RequestParam("s") double score, @RequestParam("appKey") String appKey) {
        return service.updateSectionScore(itemBankId, id, index, score, appKey);
    }

    //endregion

    //region 大题顺序调整

    /**
     * 大题顺序调整
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @param index      大题序号
     * @param m          上移/下移
     * @param appKey     appKey
     * @return return model
     */
    @PutMapping(value = "/{itemBankId}/paper/{id}/section/{index}/movement")
    public ReturnModel updateSectionOrder(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                          @PathVariable("index") String index, @RequestParam("m") boolean m, @RequestParam("appKey") String appKey) {
        return service.updateSectionOrder(itemBankId, id, index, m, appKey);
    }

    //endregion

    //region 大题试题顺序调整

    /**
     * 大题试题顺序调整
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @param index      大题序号
     * @param questionId the question id
     * @param m          上移/下移
     * @param appKey     appKey
     * @return return model
     */
    @PutMapping(value = "/{itemBankId}/paper/{id}/section/{index}/questionId/{questionId}/movement")
    public ReturnModel updateSectionQuestionOrder(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                                  @PathVariable("index") String index, @PathVariable("questionId") String questionId, @RequestParam("m") boolean m, @RequestParam("appKey") String appKey) {
        return service.updateSectionQuestionOrder(itemBankId, id, index, questionId, m, appKey);
    }

    //endregion

    //region 大题试题关联新增

    /**
     * 大题试题关联新增.
     *
     * @param itemBankId 题库id
     * @param id         试卷id
     * @param questionId 试题id
     * @param shuf       是否乱序
     * @param score      分数
     * @param appKey     appkey
     * @return the return model
     */
    @PostMapping(value = "/{itemBankId}/paper/{id}/question/{questionId}")
    public ReturnModel addSectionQuestion(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                          @PathVariable("questionId") String questionId,
                                          @RequestParam("shuf") boolean shuf,
                                          @RequestParam("s") double score,
                                          @RequestParam("appKey") String appKey) {
        return service.addSectionQuestion(itemBankId, id, questionId, shuf, score, appKey);
    }

    //endregion

    //region 大题批量试题关联新增

    /**
     * Add section question list return model.
     *
     * @param itemBankId 题库ID
     * @param id         试卷ID
     * @param questionId 试题id集合
     * @param score      分数
     * @param appKey     AppKey
     * @return return model
     */
    @PostMapping(value = "/{itemBankId}/paper/{id}/addexistquestionlist")
    public ReturnModel addExistQuestionList(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                            @RequestParam("questionId") String questionId,
                                            @RequestParam("score") double score,
                                            @RequestParam("appKey") String appKey) {
        List<String> gameids = java.util.Arrays.asList(questionId.split(","));
        return service.addExistQuestionList(itemBankId, id, gameids, score, appKey);
    }

    //endregion

    //region 大题试题修改

    /**
     * 大题试题修改
     *
     * @param itemBankId    题库ID
     * @param id            试卷ID
     * @param index         大题序号
     * @param questionId    试题id
     * @param copy          是否复制
     * @param questionModel 试题模型
     * @param appKey        所属AppKey
     * @return return model
     */
    @PutMapping(value = "/{itemBankId}/paper/{id}/section/{index}/question/{questionId}/edit")
    public ReturnModel updateSectionQuestion(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                             @PathVariable(value = "index") String index, @PathVariable(value = "questionId") String questionId,
                                             @RequestParam("copy") boolean copy, @RequestBody QuestionModel questionModel,
                                             @RequestParam("appKey") String appKey) {
        questionModel.setI4(itemBankId);
        return service.updateSectionQuestion(itemBankId, id, index, questionId, copy, questionModel, appKey);
    }

    //endregion

    //region 大题试题新增

    /**
     * 大题试题新增
     *
     * @param itemBankId    题库ID
     * @param id            试卷ID
     * @param questionModel 试题模型
     * @param shuf          the shuf
     * @param score         the score
     * @param appKey        所属AppKey
     * @return return model
     */
    @RequestMapping(value = "/{itemBankId}/paper/{id}/addnewquestion", method = RequestMethod.POST, consumes = "application/json")
    public ReturnModel addNewQuestion(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                      @RequestBody QuestionModel questionModel, @RequestParam("shuf") boolean shuf,
                                      @RequestParam("score") double score, @RequestParam("appKey") String appKey) {
        return service.addSectionQuestioninsert(itemBankId, id, questionModel, shuf, score, appKey);
    }

    //endregion

    //endregion

    //region 获取策略列表

    /**
     * 获取策略列表
     *
     * @param appKey           the app key
     * @param itemBankId       the item bank id
     * @param rulesSearchModel 策略模型
     * @return return model
     */
    @PostMapping(value = "/{itemBankId}/getruleslist")
    public ReturnModel getRulesList(@RequestParam("appKey") String appKey,
                                    @PathVariable(value = "itemBankId") String itemBankId,
                                    @RequestBody RulesSearchModel rulesSearchModel) {
        return rulesService.getRulesList(appKey, rulesSearchModel);
    }

    //endregion

    //region 策略删除

    /**
     * 策略删除
     *
     * @param itemBankId 题库id
     * @param id         策略id
     * @param appKey     appkey
     * @return return model
     */
    @DeleteMapping(value = "/{itemBankId}/rules/{id}")
    public ReturnModel removeRules(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                   @RequestParam("appKey") String appKey) {
        return rulesService.removeRules(appKey, itemBankId, id);
    }
    //endregion

    //region 策略状态修改

    /**
     * 策略状态修改
     *
     * @param itemBankId 题库id
     * @param id         策略id
     * @param appKey     appkey
     * @return return model
     */
    @PutMapping(value = "/{itemBankId}/rules/{id}/status")
    public ReturnModel updateRulesStatus(@PathVariable(value = "itemBankId") String itemBankId, @PathVariable(value = "id") String id,
                                         @RequestParam("appKey") String appKey) {
        return rulesService.updateRulesStatus(appKey, itemBankId, id);
    }
    //endregion

    //region 策略添加

    /**
     * 策略添加
     *
     * @param appKey         appkey
     * @param itemBankId     题库id
     * @param ruleInputModel 策略模型
     * @return return model
     */
    @PostMapping(value = "/{itemBankId}/rules")
    public ReturnModel addRules(@RequestParam("appKey") String appKey,
                                @PathVariable(value = "itemBankId") String itemBankId,
                                @RequestBody RuleInputModel ruleInputModel) {
        ruleInputModel.setItemBankID(itemBankId);
        return rulesService.addRule(appKey, itemBankId, ruleInputModel);
    }
    //endregion

    //region 策略修改

    /**
     * 策略修改
     *
     * @param itemBankId     题库id
     * @param appKey         appkey
     * @param ruleInputModel 策略模型
     * @return return model
     */
    @PutMapping(value = "/{itemBankId}/rules/update")
    public ReturnModel updateRules(@PathVariable(value = "itemBankId") String itemBankId, @RequestParam("appKey") String appKey,
                                   @RequestBody RuleInputModel ruleInputModel) {
        return rulesService.updateRule(appKey, itemBankId, ruleInputModel);
    }
    //endregion

    //region 获取策略信息

    /**
     * 获取策略信息
     *
     * @param appKey     appkey
     * @param itemBankId 题库id
     * @param ruleID     策略id
     * @return return model
     */
    @GetMapping(value = "/{itemBankId}/rules/{ruleID}")
    public ReturnModel getRuleInfo(@RequestParam("appKey") String appKey,
                                   @PathVariable(value = "itemBankId") String itemBankId,
                                   @PathVariable(value = "ruleID") String ruleID) {
        return rulesService.getRuleInfo(appKey, itemBankId, ruleID);
    }


    //endregion

    //region 同步组卷

    /**
     * 同步组卷
     *
     * @param itemBankId 题库ID
     * @param ruleID     策略id
     * @param paperCount 组卷数量
     * @param paperName  试卷名称
     * @param appKey     AppKey
     * @return
     */
    @PostMapping(value = "/{itemBankId}/rules/{ruleID}/createtestpaper")
    public ReturnModel createTestPaper(@RequestParam("appKey") String appKey,
                                       @PathVariable(value = "itemBankId") String itemBankId,
                                       @PathVariable(value = "ruleID") String ruleID,
                                       @RequestParam("paperCount") int paperCount,
                                       @RequestParam("paperName") String paperName) {
        return rulesService.createTestPaper(appKey, itemBankId, ruleID, paperCount, paperName);
    }
    //endregion

    //region 异步组卷

    /**
     * 异步组卷
     *
     * @param itemBankId 题库ID
     * @param ruleID     策略id
     * @param paperCount 组卷数量
     * @param paperName  试卷名称
     * @param appKey     AppKey
     * @param backUrl    回调路径
     * @return
     */
    @PostMapping(value = "/{itemBankId}/rules/{ruleID}/asynccreatetestpaper")
    public ReturnModel asyncGenerateCreateTestPaper(@RequestParam("appKey") String appKey,
                                                    @PathVariable(value = "itemBankId") String itemBankId,
                                                    @PathVariable(value = "ruleID") String ruleID,
                                                    @RequestParam("paperCount") int paperCount,
                                                    @RequestParam("paperName") String paperName,
                                                    @RequestParam("backUrl") String backUrl) throws UnsupportedEncodingException {
        return rulesService.asyncGenerateCreateTestPaper(appKey, itemBankId, ruleID, paperCount, paperName, backUrl);
    }
    //endregion

    //region 试卷导出

    /**
     * 试卷导出
     *
     * @param itemBankId  题库ID
     * @param testPaperId 试卷id
     * @param importType  导出类型
     * @param appKey      appKey
     * @return return model
     * @throws PoiException the poi exception
     * @throws ZipException the zip exception
     * @throws IOException  the io exception
     */
    @GetMapping(value = "/{itemBankId}/paper/{testPaperId}/export")
    public ReturnModel paperExportWord(@PathVariable(value = "itemBankId") String itemBankId,
                                       @PathVariable(value = "testPaperId") String testPaperId,
                                       @RequestParam("exportType") PaperImportType importType,
                                       @RequestParam("appKey") String appKey)
            throws PoiException, ZipException, IOException {
        return paperExportService.paperExportWord(itemBankId, testPaperId, importType, appKey);
    }
    //endregion

    //region 试卷导入

    /**
     * Import paper return model.
     *
     * @param importParameter the import parameter
     * @return return model
     * @throws PoiException the poi exception
     * @throws ZipException the zip exception
     * @throws IOException  the io exception
     */
    @PostMapping(value = "/{itemBankId}/paper/import")
    public ReturnModel importPaper(@PathVariable(value = "itemBankId") String itemBankId ,@RequestBody ImportParameter importParameter) {
        importParameter.setItemBankId(itemBankId);

        return service.importPaper(importParameter);
    }
    //endregion

    //region 导出试卷xml

    /**
     * Import paper return model.
     *
     * @return return model
     * @throws PoiException the poi exception
     * @throws ZipException the zip exception
     * @throws IOException  the io exception
     */
    @GetMapping(value = "/{itemBankId}/paper/exportxml")
    public ReturnModel exportPaperXML(@PathVariable(value = "itemBankId") String itemBankId,
                                      @RequestParam("appKey") String appKey) throws ZipException, IOException{

        return paperExportService.exportPaperXML(itemBankId,appKey);
    }
    //endregion

}
